<template>
  <div class="typing-container">
    <!-- 顶部控制栏 -->
    <div class="control-bar">
      <div class="left-controls">
        <el-select v-model="selectedCategory" placeholder="选择法律类别" @change="loadNewText">
          <el-option
            v-for="item in categories"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-button type="primary" @click="loadNewText" :icon="Refresh">换一段</el-button>
      </div>
      <div class="right-controls">
        <el-button-group>
          <el-button :type="mode === 'standard' ? 'primary' : ''" @click="setMode('standard')">标准模式</el-button>
          <el-button :type="mode === 'timed' ? 'primary' : ''" @click="setMode('timed')">计时模式</el-button>
        </el-button-group>
      </div>
    </div>

    <!-- 计时模式设置 -->
    <div class="time-settings" v-if="mode === 'timed' && !isTyping">
      <el-slider v-model="timeLimit" :min="1" :max="10" :marks="timeMarks" show-stops />
      <span class="time-label">练习时长: {{ timeLimit }} 分钟</span>
    </div>

    <!-- 练习区域 -->
    <div class="typing-area" v-if="!isCompleted">
      <!-- 显示文本 -->
      <div class="text-display" ref="textDisplay">
        <span
          v-for="(char, index) in displayText"
          :key="index"
          :class="getCharClass(index)"
        >{{ char }}</span>
      </div>

      <!-- 输入区域 -->
      <div class="input-area">
        <el-input
          v-model="userInput"
          placeholder="开始输入..."
          @input="handleInput"
          @keydown="handleKeyDown"
          ref="inputField"
          :disabled="isCompleted"
        />
      </div>

      <!-- 进度和统计 -->
      <div class="progress-stats">
        <el-progress :percentage="progress" :color="progressColor" />
        <TypingStats
          :accuracy="accuracy"
          :wpm="wpm"
          :time-elapsed="timeElapsed"
          :remaining-time="remainingTime"
          :mode="mode"
        />
      </div>
    </div>

    <!-- 完成练习后的结果 -->
    <div class="result-panel" v-if="isCompleted">
      <h3>练习完成!</h3>
      <div class="result-stats">
        <el-statistic title="打字速度" :value="wpm" suffix="WPM" />
        <el-statistic title="准确率" :value="accuracy" suffix="%" />
        <el-statistic title="总字数" :value="totalChars" />
        <el-statistic title="用时" :value="formatTime(timeElapsed)" />
      </div>
      <div class="action-buttons">
        <el-button type="primary" @click="startNewSession">再练一次</el-button>
        <el-button @click="loadNewText">换一段文字</el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick } from 'vue'
import { Refresh } from '@element-plus/icons-vue'
import TypingStats from './TypingStats.vue'

// 法律文本数据
const legalTexts = {
  civil: [
    "《民法典》第五百六十三条规定：有下列情形之一的，当事人可以解除合同：（一）因不可抗力致使不能实现合同目的；（二）在履行期限届满前，当事人一方明确表示或者以自己的行为表明不履行主要债务；（三）当事人一方迟延履行主要债务，经催告后在合理期限内仍未履行；（四）当事人一方迟延履行债务或者有其他违约行为致使不能实现合同目的；（五）法律规定的其他情形。",
    "《民法典》第一千一百六十五条规定：行为人因过错侵害他人民事权益造成损害的，应当承担侵权责任。依照法律规定推定行为人有过错，其不能证明自己没有过错的，应当承担侵权责任。",
    "《民法典》第四百六十五条规定：依法成立的合同，受法律保护。依法成立的合同，仅对当事人具有法律约束力，但是法律另有规定的除外。"
  ],
  criminal: [
    "《刑法》第十四条规定：明知自己的行为会发生危害社会的结果，并且希望或者放任这种结果发生，因而构成犯罪的，是故意犯罪。故意犯罪，应当负刑事责任。",
    "《刑法》第二十三条规定：已经着手实行犯罪，由于犯罪分子意志以外的原因而未得逞的，是犯罪未遂。对于未遂犯，可以比照既遂犯从轻或者减轻处罚。",
    "《刑法》第六十七条规定：犯罪以后自动投案，如实供述自己的罪行的，是自首。对于自首的犯罪分子，可以从轻或者减轻处罚。其中，犯罪较轻的，可以免除处罚。"
  ],
  administrative: [
    "《行政诉讼法》第七十条规定：行政行为有下列情形之一的，人民法院判决撤销或者部分撤销，并可以判决被告重新作出行政行为：（一）主要证据不足的；（二）适用法律、法规错误的；（三）违反法定程序的；（四）超越职权的；（五）滥用职权的；（六）明显不当的。",
    "《行政处罚法》第五十五条规定：执法人员在调查或者进行检查时，应当主动向当事人或者有关人员出示执法证件。当事人或者有关人员有权要求执法人员出示执法证件。",
    "《行政许可法》第八条规定：公民、法人或者其他组织依法取得的行政许可受法律保护，行政机关不得擅自改变已经生效的行政许可。"
  ]
}

// 状态和数据
const categories = [
  { value: 'civil', label: '民法' },
  { value: 'criminal', label: '刑法' },
  { value: 'administrative', label: '行政法' }
]
const selectedCategory = ref('civil')
const displayText = ref('')
const userInput = ref('')
const currentPosition = ref(0)
const correctChars = ref(0)
const totalChars = ref(0)
const startTime = ref(null)
const timeElapsed = ref(0)
const isTyping = ref(false)
const isCompleted = ref(false)
const mode = ref('standard') // 'standard' or 'timed'
const timeLimit = ref(3) // 分钟
const remainingTime = ref(0)
const inputField = ref(null)
const textDisplay = ref(null)
let timer = null
let countdownTimer = null

// 计算属性
const accuracy = computed(() => {
  if (currentPosition.value === 0) return 100
  return Math.round((correctChars.value / currentPosition.value) * 100)
})

const wpm = computed(() => {
  if (timeElapsed.value < 5) return 0 // 至少5秒才计算WPM
  const minutes = timeElapsed.value / 60
  const words = currentPosition.value / 5 // 假设5个字符为一个单词
  return Math.round(words / minutes)
})

const progress = computed(() => {
  if (displayText.value.length === 0) return 0
  return Math.round((currentPosition.value / displayText.value.length) * 100)
})

const progressColor = computed(() => {
  if (accuracy.value < 80) return '#f56c6c'
  if (accuracy.value < 95) return '#e6a23c'
  return '#67c23a'
})

const timeMarks = computed(() => {
  const marks = {}
  for (let i = 1; i <= 10; i++) {
    marks[i] = i + '分'
  }
  return marks
})

// 方法
const loadNewText = () => {
  const texts = legalTexts[selectedCategory.value]
  displayText.value = texts[Math.floor(Math.random() * texts.length)]
  resetSession()
}

const resetSession = () => {
  userInput.value = ''
  currentPosition.value = 0
  correctChars.value = 0
  totalChars.value = displayText.value.length
  timeElapsed.value = 0
  isTyping.value = false
  isCompleted.value = false
  remainingTime.value = timeLimit.value * 60

  if (timer) clearInterval(timer)
  if (countdownTimer) clearInterval(countdownTimer)

  nextTick(() => {
    inputField.value.focus()
  })
}

const startNewSession = () => {
  resetSession()
}

const setMode = (newMode) => {
  mode.value = newMode
  loadNewText()
}

const handleInput = () => {
  if (!isTyping.value) {
    isTyping.value = true
    startTime.value = new Date()

    // 启动计时器
    timer = setInterval(() => {
      timeElapsed.value = Math.floor((new Date() - startTime.value) / 1000)

      // 计时模式检查
      if (mode.value === 'timed' && remainingTime.value > 0) {
        remainingTime.value = timeLimit.value * 60 - timeElapsed.value
        if (remainingTime.value <= 0) {
          completeSession()
        }
      }
    }, 1000)
  }

  // 限制输入长度
  if (userInput.value.length > displayText.value.length) {
    userInput.value = userInput.value.slice(0, displayText.value.length)
  }

  // 更新当前位置
  currentPosition.value = userInput.value.length

  // 计算正确字符数
  correctChars.value = 0
  for (let i = 0; i < currentPosition.value; i++) {
    if (userInput.value[i] === displayText.value[i]) {
      correctChars.value++
    }
  }

  // 检查是否完成
  if (currentPosition.value === displayText.value.length) {
    completeSession()
  }
}

const handleKeyDown = (e) => {
  // 阻止退格键删除已正确输入的内容
  if (e.key === 'Backspace' && e.target.selectionStart < currentPosition.value) {
    e.preventDefault()
  }
}

const completeSession = () => {
  isCompleted.value = true
  isTyping.value = false
  clearInterval(timer)
  clearInterval(countdownTimer)
}

const getCharClass = (index) => {
  if (index >= currentPosition.value) return 'untyped'
  if (userInput.value[index] === displayText.value[index]) return 'correct'
  return 'incorrect'
}

const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins}分${secs}秒`
}

// 初始化
onMounted(() => {
  loadNewText()
})
</script>

<style lang="scss" scoped>
.typing-container {
  max-width: 900px;
  margin: 0 auto;
  padding: 20px;
  font-family: "Microsoft YaHei", sans-serif;
}

.control-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;

  .left-controls {
    display: flex;
    gap: 10px;
  }
}

.time-settings {
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;
  text-align: center;

  .time-label {
    display: inline-block;
    margin-top: 10px;
    font-weight: bold;
  }
}

.typing-area {
  background-color: white;
  border-radius: 4px;
  padding: 20px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.text-display {
  font-size: 18px;
  line-height: 1.8;
  margin-bottom: 20px;
  padding: 15px;
  background-color: #f9f9f9;
  border-radius: 4px;
  min-height: 150px;

  span {
    position: relative;

    &.correct {
      color: #67c23a;
    }

    &.incorrect {
      color: #f56c6c;
      text-decoration: underline;
    }

    &.untyped {
      color: #606266;
    }

    &:after {
      content: '';
      position: absolute;
      left: 0;
      bottom: -2px;
      width: 100%;
      height: 2px;
      background-color: transparent;
    }
  }
}

.input-area {
  margin-bottom: 20px;

  :deep(.el-input__inner) {
    font-size: 18px;
    padding: 15px;
    height: 60px;
  }
}

.progress-stats {
  margin-top: 20px;
}

.result-panel {
  text-align: center;
  padding: 30px;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

  h3 {
    color: #409eff;
    margin-bottom: 20px;
  }

  .result-stats {
    display: flex;
    justify-content: space-around;
    margin: 30px 0;

    :deep(.el-statistic) {
      .el-statistic__head {
        font-size: 16px;
        color: #909399;
        margin-bottom: 10px;
      }

      .el-statistic__content {
        font-size: 24px;
        font-weight: bold;
        color: #2c3e50;
      }
    }
  }

  .action-buttons {
    margin-top: 30px;
  }
}

@media (max-width: 768px) {
  .control-bar {
    flex-direction: column;
    gap: 10px;

    .left-controls, .right-controls {
      width: 100%;
    }
  }

  .result-stats {
    flex-direction: column;
    gap: 20px;
  }
}
</style>
